/* eslint-disable no-undef,linebreak-style,import/no-unresolved,import/extensions,generator-star-spacing,prefer-const,comma-dangle,arrow-parens,object-curly-spacing,semi,comma-spacing,quotes,quote-props,no-use-before-define,key-spacing,no-unneeded-ternary,no-unused-expressions,no-multi-spaces,eol-last */

import {
    message,
} from 'ant-design-vue';

export default (top) => {
    function * asyncGetFetchData(x) {
        let defaultObj = {
            data: '',
            err: ''
        };
        let nextx = true;
        let datas = [];
        let suc = null;
        let fail = null;
        while (nextx) {
            nextx = yield x;
            if (nextx instanceof Function) {
                if (suc) {
                    fail = nextx;
                } else {
                    suc = nextx;
                }
            } else if (typeof nextx === 'object') {
                nextx = Object.assign({}, defaultObj, nextx);
                if (nextx.err) {
                    fail(nextx);
                    break;
                } else {
                    datas.push(nextx.data);
                }
            } else {
                break;
            }
        }
        return suc(datas);
    }

    const defaultAsyncFetchEvent =
        (args) => {
            let asyncGetFetchDataObj = asyncGetFetchData(0);
            top.loading = true;
            return new Promise((s, f) => {
                asyncGetFetchDataObj.next(0);
                asyncGetFetchDataObj.next(s);
                asyncGetFetchDataObj.next(f);
                fetchEvent.fetchEventApi(args, obj => {
                    setTimeout(() => {
                        asyncGetFetchDataObj.next(obj)
                    });
                })
            })
                .catch(({err}) => {
                    message.error(err);
                });
        };

    const defaultFetchEvent =
        (args) => {
            top.loading = true;
            return new Promise((s, f) => {
                fetchEvent.fetchEventApi(args, ({err, data}) => {
                    top.loading = false;
                    if (err) {
                        f({err, data});
                    } else {
                        s(data)
                    }
                })
            })
                .catch(({err}) => {
                    message.error(err);
                });
        };

    const onlySuccessPromise =
        (ev,args) => new Promise((s) => {
            ev(s,...args);
        });

    const projectSettingFileName = 'setting.json';

    const __config__ = {
        folders: {
            draught_index_calculation_module: {
                boundary: null,
                log: null,
                result: null,
                source: null,
                tmp: null
            },
            dss: null,
            ET: {
                result: null
            },
            Lake_extraction: null,
            planting_structure: null
        },
        defaultProjectSetting: {
            smbDisk: 'Z'
        },
        defaultMysqlSetting: {
            "host": "127.0.0.1",
            "user": "root",
            "password": "root",
            "database": "db"
        },
        root() {
            return fetchEvent.extendMethod.paths.projectRoot;
        },
        projectSetting() {
            return fetchEvent.extendMethod.path.join(fetchEvent.extendMethod.paths.projectRoot,projectSettingFileName);
        },
        getProjectConfig() {
            let path = __config__.projectSetting();
            return fetchEventUtils.file.existsWithReadOrCreate(
                path,
                JSON.stringify(__config__.defaultProjectSetting));
        },
        getMysqlConfig(path) {
            return fetchEventUtils.file.existsWithReadOrCreate(
                path,
                JSON.stringify(__config__.defaultMysqlSetting));
        },
        checkFoldersExist(disk) {
            function di(obj) {
                let ret = [];
                for (let i in obj) {
                    if (obj[i]) {
                        di(obj[i]).map(_ => {
                            _.unshift(i);
                            ret.push(_);
                        });
                    } else {
                        ret.push([i]);
                    }
                }
                return ret;
            }
            return fetchEventUtils.dir.checkFoldersExsit(di(__config__.folders).map(_ => {
                _.unshift(`${disk}:\\`);
                return _;
            }));
        }
    };

    const path_ = fetchEvent.extendMethod.path;

    const fetchEventUtils = {
        dir: {
            defaultEvent: (eventName,path) => {
                let dir = fetchEvent.fetchEventAction.dir[eventName]();
                dir.param.path = path;
                return dir;
            },
            getFilesUnderPath: (path, ext, withInfo) => {
                let dir = fetchEvent.fetchEventAction.dir.getFilesUnderPath();
                ext = ext ? ext : [];
                dir.param = {
                    path,
                    ext: (ext instanceof Array ? ext : [ext]),
                    withInfo: !!withInfo
                };
                return defaultFetchEvent(dir);
            },
            isEmpty: path => defaultFetchEvent(fetchEventUtils.dir.defaultEvent('isEmpty',path)),
            getAll: (path, childPath, isTree, excludePath) => {
                let dirs = fetchEvent.fetchEventAction.dir.getAll();
                dirs.param = {
                    path, childPath, isTree, excludePath
                };
                return defaultFetchEvent(dirs);
            },
            mkdir: path => defaultFetchEvent(fetchEventUtils.dir.defaultEvent('mkdir',path)),
            removeFileOrDir: path => defaultFetchEvent(fetchEventUtils.dir.defaultEvent('removeFileOrDir',path)),
            checkFoldersExsit: paths => {
                let dirs = fetchEvent.fetchEventAction.dir.checkFoldersExsit();
                dirs.param.folders = paths;
                return defaultFetchEvent(dirs);
            },
            copyDirSync: (src, dist, root) => {
                let cpDir = fetchEvent.fetchEventAction.dir.copyDirSync();
                cpDir.param = {
                    src,
                    dist,
                    root
                };
                return defaultFetchEvent(cpDir);
            },
            copyDir: (src, dist, root) => {
                let cpDir = fetchEvent.fetchEventAction.dir.copyDir();
                cpDir.param = {
                    src,
                    dist,
                    root
                };
                // fetchEvent.fetchEventApi(cpDir, cb);
                return defaultAsyncFetchEvent(cpDir);
            },
        },
        file: {
            defaultEvent: (eventName, fileName, content, binary) => {
                let file = fetchEvent.fetchEventAction.file[eventName]();
                file.param = {
                    fileName,
                    content: content || '',
                    binary: !!binary
                };
                return file;
            },
            append: (fileName, content) =>
                defaultFetchEvent(fetchEventUtils.file.defaultEvent("append",fileName, content)),
            write: (fileName, content, binary) =>
                defaultFetchEvent(fetchEventUtils.file.defaultEvent("write",fileName, content, binary)),
            read: (fileName, content, binary) =>
                defaultFetchEvent(fetchEventUtils.file.defaultEvent("read",fileName, content, binary)),
            exists: (fileName) =>
                defaultFetchEvent(fetchEventUtils.file.defaultEvent("read",fileName)),
            existsWithReadOrCreate: (fileName,content) =>
                defaultFetchEvent(fetchEventUtils.file.defaultEvent("existsWithReadOrCreate",fileName,content)),
            copyFile: (src,dist) => {
                let file = fetchEvent.fetchEventAction.file.copyFile();
                file.param = {
                    source: src,
                    target: dist
                };
                return defaultFetchEvent(file);
            },
            copyFileWithReplace: (src,dist,replaceField,replaceContent) => {
                let file = fetchEvent.fetchEventAction.file.copyFileWithReplace();
                file.param = {
                    source: src,
                    target: dist,
                    replaceField: replaceField || '',
                    replaceContent: replaceContent || '',
                };
                return defaultFetchEvent(file);
            }
        },
        os: {
            get:() => defaultFetchEvent(fetchEvent.fetchEventAction.os.get)
        },
        request: {
            defaultEvent: (eventName,url, form ,header) => {
                let req = fetchEvent.fetchEventAction.request[eventName]();
                req.param = {
                    url,
                    form: form || {},
                    header: header || {}
                };
                return req;
            },
            get: (url, form ,header) => defaultFetchEvent(fetchEventUtils.request.defaultEvent('get',url, form, header)),
            post: (url, form ,header) => defaultFetchEvent(fetchEventUtils.request.defaultEvent('post',url, form, header)),
        },
        command: {
            copyDir: (src,dist) => {
                let cmd = fetchEvent.fetchEventAction.command.copyDir();
                cmd.param = {
                    source: src,
                    target: dist,
                };
                return defaultFetchEvent(cmd);
            }
        },
        browserView: {
            openBrowserView(width,height,frame,modal,url,closeUrl) {
                let browser = fetchEvent.fetchEventAction.browserView.openBrowserView();
                browser.param = {width,height,frame,modal,url,closeUrl};
                return defaultFetchEvent(browser);
            }
        },
        spawn: {
            runCommand(command,args) {
                let spawn = fetchEvent.fetchEventAction.spawn.runCommand();
                spawn.param = { command , args };
                return defaultFetchEvent(spawn);
            }
        },
        mysql: {
            checkConfig: () => defaultFetchEvent(fetchEvent.fetchEventAction.mysql.checkConfig()),
            checkConnection: () => defaultFetchEvent(fetchEvent.fetchEventAction.mysql.checkConnection()),
            query: sql => {
                let query = fetchEvent.fetchEventAction.mysql.query();
                query.param.sql = sql;
                return defaultFetchEvent(query);
            },
            configPath: () => defaultFetchEvent(fetchEvent.fetchEventAction.mysql.configPath())
        },
        MDialog: {
            getFile(title, defaultPath, buttonLabel, filters) {
                let obj = {};
                title       ? obj.title = title             : false;
                defaultPath ? obj.defaultPath = defaultPath : false;
                buttonLabel ? obj.buttonLabel = buttonLabel : false;
                filters     ? obj.filters = filters         : false;
                return defaultFetchEvent(Object.assign(
                    fetchEvent.fetchEventAction.MDialog.getFile(),{
                        param: obj
                    }
                ));
            },
            getDir(title, defaultPath, buttonLabel) {
                let obj = {};
                title       ? obj.title = title             : false;
                defaultPath ? obj.defaultPath = defaultPath : false;
                buttonLabel ? obj.buttonLabel = buttonLabel : false;
                return defaultFetchEvent(Object.assign(
                    fetchEvent.fetchEventAction.MDialog.getDir(),{
                        param: obj
                    }
                ));
            },
            getSaveFile(title, defaultPath, buttonLabel, filters) {
                let obj = {};
                title       ? obj.title = title             : false;
                defaultPath ? obj.defaultPath = defaultPath : false;
                buttonLabel ? obj.buttonLabel = buttonLabel : false;
                filters     ? obj.filters = filters         : false;
                return defaultFetchEvent(Object.assign(
                    fetchEvent.fetchEventAction.MDialog.getSaveFile(),{
                        param: obj
                    }
                ));
            },
            getSaveDir(title, defaultPath, buttonLabel) {
                let obj = {};
                title       ? obj.title = title             : false;
                defaultPath ? obj.defaultPath = defaultPath : false;
                buttonLabel ? obj.buttonLabel = buttonLabel : false;
                return defaultFetchEvent(Object.assign(
                    fetchEvent.fetchEventAction.MDialog.getSaveDir(),{
                        param: obj
                    }
                ));
            },
        },
        dialog: {
            getFile(title, defaultPath, buttonLabel, filters) {
                let obj = {};
                title       ? obj.title = title             : false;
                defaultPath ? obj.defaultPath = defaultPath : false;
                buttonLabel ? obj.buttonLabel = buttonLabel : false;
                filters     ? obj.filters = filters         : false;
                return onlySuccessPromise(fetchEvent.dialog.getFile,[obj]);
            },
            getDir(title, defaultPath, buttonLabel) {
                let obj = {};
                title       ? obj.title = title             : false;
                defaultPath ? obj.defaultPath = defaultPath : false;
                buttonLabel ? obj.buttonLabel = buttonLabel : false;
                return onlySuccessPromise(fetchEvent.dialog.getDir,[obj]);
            },
            getSaveFile(title, defaultPath, buttonLabel, filters) {
                let obj = {};
                title       ? obj.title = title             : false;
                defaultPath ? obj.defaultPath = defaultPath : false;
                buttonLabel ? obj.buttonLabel = buttonLabel : false;
                filters     ? obj.filters = filters         : false;
                return onlySuccessPromise(fetchEvent.dialog.getSaveFile,[obj]);
            },
            getSaveDir(title, defaultPath, buttonLabel) {
                let obj = {};
                title       ? obj.title = title             : false;
                defaultPath ? obj.defaultPath = defaultPath : false;
                buttonLabel ? obj.buttonLabel = buttonLabel : false;
                return onlySuccessPromise(fetchEvent.dialog.getSaveDir,[obj]);
            },
        },
        plugin: {
            excel: {
                writeExcel(filename, results, rowHeight) {
                    const wxlsx = fetchEvent.fetchEventAction.excel.writeExcel();
                    wxlsx.param = {
                        filename,
                        results,
                        rowHeight
                    };
                    return defaultFetchEvent(wxlsx);
                },
                writeCSV(filename, results) {
                    const wcsv = fetchEvent.fetchEventAction.excel.writeCSV();
                    wcsv.param.filename = filename;
                    wcsv.param.results = results;
                    return defaultFetchEvent(wcsv);
                },
                readExcel(filename, header) {
                    const rxlsx = fetchEvent.fetchEventAction.excel.readExcel();
                    rxlsx.param = {
                        filename,
                        header
                    };
                    return defaultFetchEvent(rxlsx);
                },
                readCSV(filename) {
                    const rcsv = fetchEvent.fetchEventAction.excel.readCSV();
                    rcsv.param.filename = filename;
                    return defaultFetchEvent(rcsv);
                },
                dbToExcel(filename, sql, keyLabel, sheetName) {
                    const rcsv = fetchEvent.fetchEventAction.excel.dbToExcel();
                    rcsv.param = {
                        filename,
                        sql,
                        keyLabel,
                        sheetName
                    };
                    return defaultFetchEvent(rcsv);
                }
            }
        },
        __async__: {
            dir: {
                copyDir: (cb, src, dist, root) => {
                    let cpDir = fetchEvent.fetchEventAction.dir.copyDir();
                    cpDir.param = {
                        src,
                        dist,
                        root
                    };
                    fetchEvent.fetchEventApi(cpDir, cb);
                },
            }
        },
        __config__,
        utils: {
            /**
             * path = 'c:\\a\\b\\c.txt'
             * dirver = 'd'
             * return 'd:\\a\\b\\c.txt'
             * */
            changeDriver(path, driver) {
                return path_.join(driver + ':',path_.relative(path_.parse(path).root,path));
            },
            /**
             * @param path      'c:\\a\\b\\c.txt'
             * @param target    'd:\\a'
             * @return          'd:\\a\\c.txt'
             */
            copyFileToPath(path, target) {
                return path_.join(target, path_.basename(path));
            }
        }
    };
    return fetchEventUtils;
}